<?php

namespace app\service;

/**
 * 漏桶算法
 * Class LeakyBucket
 */
class LeakyBucket {

    private $last_req_time; //上一次请求的时间
    public $capacity; //桶的容量
    public $rate; //水漏出的速度(个/秒)
    public $water; //当前水量(当前累积请求数)

    public function __construct($capacity=null, $rate=null) {
        $this->last_req_time = time();
        $this->capacity = $capacity ?? 100;
        $this->rate = $rate ?? 20;
        $this->water = 0;
    }

    public function grant() {
        $now = time();
        $water = max(0, $this->water - ($now - $this->last_req_time) * $this->rate);// 先执行漏水，计算剩余水量
        $this->water = $water;
        $this->last_req_time = $now;
        if ($water < $this->capacity) {
            // 尝试加水，并且水还未满
            $this->water += 1;
            return true;
        }
        // 水满，拒绝加水
        return false;
    }
}